package com.iceclean.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.iceclean.po.User;
import com.iceclean.service.UserService;
import com.iceclean.serviceImpl.UserServiceImpl;
import com.iceclean.util.ServiceAgent;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.UUID;

/**
 * @author : Ice'Clean
 * @date : 2021-05-07
 *
 * 接收所有与用户操作有关的请求
 */
@WebServlet(name = "UserServlet", value = "/UserServlet")
public class UserServlet extends BaseServlet {

    /**
     * 用户服务的动态代理
     */
    UserService userService = (UserService) new ServiceAgent(new UserServiceImpl()).getAgent();

    /**
     * 执行用户登录功能
     * @param request 请求
     * @param response 响应
     * @throws IOException IO异常
     */
    public void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
        System.out.println("【1】调用了：login");

        // 获取用户名和密码
        String userName = request.getParameter("userName");
        String userPass = request.getParameter("userPass");

        // 执行登录判断
        User user = userService.loginUser(userName, userPass);

        // 不为 null 表示登录成功
        response.setCharacterEncoding("utf-8");
        if (user != null) {
            // 成功的话保存用户信息
            HttpSession session = request.getSession();
            session.setAttribute("user", user);
            response.getWriter().write("success");
        } else {
            response.getWriter().write("error");
        }
    }

    /**
     * 执行用户注册哦功能
     * @param request 请求
     * @param response 响应
     * @throws IOException IO异常
     */
    public void register(HttpServletRequest request, HttpServletResponse response) throws IOException {
        System.out.println("【2】调用了：register");

        // 获取用户名和密码以及预留的邮箱
        String userName = request.getParameter("userName");
        String userPass = request.getParameter("userPass");
        String userPostBox = request.getParameter("userPostBox");
        System.out.println(userPostBox);

        // 判断用户名是否已存在
        response.setContentType("text/html;charset=utf-8");
        ObjectMapper mapper = new ObjectMapper();
        if (userService.findUserByUserName(userName) == null) {
            // 注册新用户，并将用户实体发送给给前端
            User user = userService.createNewUser(userName, userPass, userPostBox);
            response.getWriter().write(mapper.writeValueAsString(user));
        }else {
            // 返回空用户
            response.getWriter().write(mapper.writeValueAsString(new User()));
        }
    }

    public void getUserBySession(HttpServletRequest request, HttpServletResponse response) throws IOException {
        System.out.println("【3】调用了：getUserBySession");

        // 获取当前存放在 session 中的 user 对象，即已经绑定了的用户
        User user =  (User) request.getSession().getAttribute("user");
        System.out.println(user);
        ObjectMapper mapper = new ObjectMapper();

        response.setCharacterEncoding("utf-8");
        response.getWriter().write(mapper.writeValueAsString(user));
    }

    public void getUserByBy(HttpServletRequest request, HttpServletResponse response) throws IOException {
        int userId = Integer.parseInt(request.getParameter("userId"));
        User user = userService.findUserById(userId);
        ObjectMapper mapper = new ObjectMapper();

        response.setCharacterEncoding("utf-8");
        response.getWriter().write(mapper.writeValueAsString(user));

    }

    public void getUserById(HttpServletRequest request, HttpServletResponse response) throws IOException {
        System.out.println("【4】调用了：getUserById");

        // 通过 id 获取用户数据
        int userId = Integer.parseInt(request.getParameter("userId"));

        User user = userService.findUserById(userId);
        ObjectMapper mapper = new ObjectMapper();

        response.setCharacterEncoding("utf-8");
        response.getWriter().write(mapper.writeValueAsString(user));
    }

    public void changeUser(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 获取前端传过来的数据
        request.setCharacterEncoding("utf-8");
        String nickName = request.getParameter("nickName");
        String userResume = request.getParameter("userResume");
        String userSex = request.getParameter("userSex");

        System.out.println("收到的数据：" + nickName + "  " + userResume + "  " + userSex);

        // 修改 session 中的 user 对象并保存到数据库中
        User user = (User) request.getSession().getAttribute("user");
        user.setNickName(nickName);
        user.setUserResume(userResume);
        user.setUserSex(Integer.parseInt(userSex));

        // 保存到数据库中
        userService.updateUser(user);

        response.getWriter().write("success");
    }

    /**
     * 修改用户密码
     * 有两种情况：
     * （1）是主动修改密码，知道旧密码
     * （2）是忘记密码，需要输入预留邮箱
     */
    public void changeUserPass(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 接收旧密码和新密码
        String oldUserPass = request.getParameter("oldUserPass");
        String newUserPass = request.getParameter("newUserPass");

        // 也有可能是传入预留邮箱
        String userPostBox = request.getParameter("userPostBox");

        if (oldUserPass != null) {
            // 旧密码不为空说明是主动修改密码，检查旧密码
            // 获取绑定的用户对象
            User user = (User) request.getSession().getAttribute("user");
            // 匹配用户名与密码，检查旧密码是否正确
            User loginUser = userService.loginUser(user.getUserName(), oldUserPass);

            // 如果得到的用户不为空，则说明旧密码输入正确，给予修改密码
            if (loginUser != null) {
                // 修改用户密码（需要加密）
                user.setUserPass(userService.changeCode(newUserPass, user.getUserName()));
                // 保存到数据库中
                userService.updateUser(user);
                // 保存到 session 中
                request.getSession().setAttribute("user", user);
                // 返回成功到前端
                response.getWriter().write("success");
            } else {
                // 得不到说明旧密码输入错误，返回失败到前端
                response.getWriter().write("fail");
            }
        } else {
            // 为空说明是忘记密码，检查预留邮箱
            // 获取用户输入的用户名
            String userName = request.getParameter("userName");
            User user = userService.findUserByUserName(userName);

            // 用户预留邮箱对上了，给予修改密码
            if (user != null && user.getUserPostBox().equals(userPostBox)) {
                user.setUserPass(userService.changeCode(newUserPass, userName));
                // 保存到数据库中
                userService.updateUser(user);
                // 返回成功到前端
                response.getWriter().write("success");
            } else {
                // 邮箱对不上，返回失败到前端
                response.getWriter().write("fail");
            }
        }
    }

    public void setUserHead(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 设置请求的解析为 utf-8 ，处理文件名称含有中文的
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        System.out.println("我们收到啦！");

        // 判断是否为为多段数据
        if (ServletFileUpload.isMultipartContent(request)) {
            // 获取到当前操作的用户
            User user = (User) request.getSession().getAttribute("user");

            // 获取存放头像的文件夹路径，并判断该文件夹是否存在，不存在则新建一个
            String userHeadPath = getServletContext().getRealPath("/user_head/");
            File headFile = new File(userHeadPath);

            // 如果文件夹不存在并且创建文件夹失败，记录下错误，返回
            if (!headFile.exists() && !headFile.mkdir()) {
                System.out.println("用户头像文件夹不存在且创建失败！");
                return;
            }

            try {
                // 获取到文件上传对象
                FileItemFactory fileItemFactory = new DiskFileItemFactory();
                ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);

                // 获取表单项
                List<FileItem> fileItems = servletFileUpload.parseRequest(request);
                System.out.println("收到的数据：" + fileItems.size());
                // 取出数据
                for (FileItem fileItem : fileItems) {
                    // 如果是文件的话
                    System.out.println("是头像吗？" + !fileItem.isFormField());
                    if (!fileItem.isFormField()) {
                        // 查看用户有无设置过头像，有则删除掉
                        if (user.getUserHead() != null) {
                            File oldHead = new File(userHeadPath + user.getUserHead());
                            oldHead.delete();
                        }

                        System.out.println("头像名称：" + fileItem.getName());
                        // 为用户设置新头像
                        // 采用 uuid 加入到文件命中，防止文件名相同导致覆盖
                        String newUserHead = UUID.randomUUID().toString() + fileItem.getName();
                        fileItem.write(new File(userHeadPath + newUserHead));

                        // 将新用户头像的路径保存进数据库
                        user.setUserHead(newUserHead);
                        userService.updateUser(user);

                        // 保存到 session 中
                        request.getSession().setAttribute("user", user);

                        // 返回图片的名称，到前端去更新
                        response.getWriter().write(newUserHead);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("并没有多段！");
            response.getWriter().write("error");
        }
    }
}
